package kr.as3.samples.captureyourscreen
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.NativeWindowSystemChrome;
	import flash.display.NativeWindowType;
	import flash.display.Screen;
	import flash.display.Shape;
	import flash.display.StageDisplayState;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	
	import kr.as3.display.NewWindow;
	
	public class FullscreenCaptured extends NewWindow
	{
		private var backBitmap: Bitmap;
		private var backBitmapData: BitmapData;
		
		private var bitmap: Bitmap;
		private var bitmapData: BitmapData;
		
		private var frame: CaptureFrame;
		
		private var maskFrame: Shape;
		
		public function FullscreenCaptured( $bitmapData: BitmapData )
		{
			this.bitmapData = $bitmapData;
			this.bitmap = new Bitmap( this.bitmapData );
			
			this.backBitmapData = this.bitmapData.clone();
			this.backBitmapData.colorTransform( this.backBitmapData.rect, new ColorTransform( 0.8, 0.8, 0.8 ) );
			this.backBitmap = new Bitmap( this.backBitmapData );
			this.backBitmap.filters = [ new BlurFilter( 5, 5, 5 ) ];
			
			super( NativeWindowType.NORMAL, NativeWindowSystemChrome.NONE, false );
			
			this.stage.addChild( this.backBitmap );
			this.stage.addChild( this.bitmap );
			this.addEventListener( MouseEvent.CLICK, clickListener );
			
			var screenBounds: Rectangle = Screen.mainScreen.bounds;
			
			this.width = screenBounds.width;
			this.height = screenBounds.height;
			
			this.activate();
			
			this.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
			this.stage.addEventListener( Event.RESIZE, closeWindow );
			
			this.frame = new CaptureFrame();
			this.frame.x = ( screenBounds.width - this.frame.width ) / 2;
			this.frame.y = ( screenBounds.height - this.frame.height ) / 2;
			this.frame.dragArea.addEventListener( MouseEvent.MOUSE_DOWN, frameDragStart );
			this.frame.addEventListener( "areaDown", areaDownListener );
			this.stage.addChild( this.frame );
			
			this.maskFrame = new Shape();
			this.maskFrame.graphics.beginFill( 0 );
			this.maskFrame.graphics.drawRect( 0, 0, this.frame.bounds.width, this.frame.bounds.height );
			this.stage.addChild( this.maskFrame );
			
			this.bitmap.mask = this.maskFrame;
			
			this.frameFollow();
		}
		
		private function areaDownListener( e: Event ): void
		{
			this.frame.dragArea.removeEventListener( MouseEvent.MOUSE_DOWN, frameDragStart );
			this.stage.removeChild( this.backBitmap );
			this.stage.removeChild( this.bitmap );
			
			this.stage.removeEventListener( Event.RESIZE, closeWindow );
			this.stage.displayState = StageDisplayState.NORMAL;
			
			var captured: BitmapData = new BitmapData( this.frame.area.width, this.frame.area.height );
			
			var mat: Matrix = new Matrix();
			mat.translate( -this.frame.x, -this.frame.y );
			
			captured.draw( this.bitmapData, mat );
			
			this.frame.addCapture( captured );
			
			this.x = this.frame.getBounds( this.stage ).x;
			this.y = this.frame.getBounds( this.stage ).y;
			this.width = this.frame.width;
			this.height = this.frame.height;
			this.frame.x = -this.frame.getBounds( this.frame ).x;
			this.frame.y = -this.frame.getBounds( this.frame ).y;
		}
		
		private function closeWindow( e: Event ): void
		{
			if( this.stage.displayState != StageDisplayState.FULL_SCREEN_INTERACTIVE )
			{
				this.stage.removeChild( this.frame );
				this.stage.removeChild( this.backBitmap );
				this.stage.removeChild( this.bitmap );
				this.close();
			}
		}
		
		private function frameDragStart( e: MouseEvent ): void
		{
			this.frame.startDrag();
			
			this.stage.addEventListener( Event.ENTER_FRAME, frameFollow );
			
			this.stage.addEventListener( MouseEvent.MOUSE_UP, frameDragStop );
			this.stage.addEventListener( Event.MOUSE_LEAVE, frameDragStop );
		}
		
		private function frameFollow( e: Event = null ): void
		{
			this.maskFrame.x = this.frame.x;
			this.maskFrame.y = this.frame.y;
		}
		
		private function frameDragStop( e: Event ): void
		{
			this.frame.stopDrag();
			
			this.stage.removeEventListener( Event.ENTER_FRAME, frameFollow );
			
			this.stage.removeEventListener( MouseEvent.MOUSE_UP, frameDragStop );
			this.stage.removeEventListener( Event.MOUSE_LEAVE, frameDragStop );
		}
		
		private function clickListener( e: MouseEvent ): void
		{
			this.close();
		}
	}
}